package com.example.kotlinstudy.activity.KTBase.stage1

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import com.example.kotlinstudy.bean.Student
import com.example.kotlinstudy.bean.UserBean
import com.example.kotlinstudy.util.KtBase22


class KotlineTestActivity : ComponentActivity() {
    var a = 1
    var c: Int = 2
    val b = 2


    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        a = 3
        Log.d("add2", "" + add2(1, 2))

        /*方法的灵活调用*/
        getUserInfo1()
        getUserInfo1("hahahh")
        getUserInfo1("hahah", 20)
        getUserInfo1(age = 20)
        getUserInfo1(name = "张三")

        /*声明函数方法一*/
        val createMethord1: () -> String
        //匿名函数不要写return，最后一行就是返回值
        createMethord1 = {
            "我是返回的字符串"
        }

        /*声明函数方法二*/
        val createMethod2: (Int, Int, Int) -> Int = { num1, num2, num3 ->
            num1 + num3
        }


    }

    /**
     *方法
     * 1.kotlin的when 和if 实现必须要有else语句的分支
     * 2.在Kotlin中，Number是一个类别，它是Int、Double、Float、Long等数字类型的父类。Int是其中一个具体的类型，用于表示32位整数。
     * 3、when的使用
     */
    fun test() {

    }


    fun add(a: Int, b: Int): Int {
        return a + b
    }

    fun getUserInfo(name: String, age: Int): String {
        return "姓名${name} ,年龄 $age"
    }

    fun add1(a: Int, b: Int): Int = a + b
    fun add2(a: Int, b: Int) = a + b

    fun getScore(name: String) = when (name) {
        "Tom" -> {
            "及格"
        }

        else -> {
            "不及格"
        }

    }

    fun getDay(day: Int) = when (day) {
        1 -> "1"
        2 -> "2"
        3 -> "3"
        4 -> "4"
        else -> {
            "hahha"
        }
    }

    /**
     * when不传递形参,更加灵活
     * companion object(伴生对象)
     */
    fun getScore1(name: String) = when {
        name.startsWith("张") -> {
            "良好"
        }

        name == "Tom" -> "及格"

        else -> {
            "不及格"
        }

    }


    private fun checkNumber(num: Number): String {
        when (num) {
            is Int -> {
                return "2"
            }

            is Double -> {
                return "2"
            }

            else -> {
                return "3"
            }
        }


    }


    /**
    ======================********三、循环*********=======================
    1、区间
    2、for in

     */

    val rang = 0..10//[0,10]

    fun circleNumber() {
        val numbers = 0..4
        for (i in numbers) {
            System.out.println("结果是：  " + i)
        }
    }

    fun circleNumber1() {
        for (i in 0 until 10) {//[0,9]
            System.out.println("结果是：  " + i)
        }
    }

    /**
     * step 步长
     */
    fun circleNumber2() {
        for (i in 0 until 10 step 2) {//[0,2,4,6,8]
            System.out.println("结果是：  " + i)
        }
    }

    /**
     * downTo降序
     */
    fun circleNumber3() {
        for (i in 10 downTo 1 step 2) {//10 8 6 4 2
            System.out.println("结果是：  " + i)

        }


    }


    /**
    ======================********三、对象*********=======================
     */
    /**
     * 1.子类需要使用父类的参数通过构造函数传递 open才能传递
     * 2.主构造方法 init方法，替代以前的construct方法
     * 3、次构造函数constructor实现
     * 4、权限修饰符
     * public(open) private protect internal
     * 5、data数据类的class,不需要写get，set，hashCode，equals，toString等方法
     *
     */

    fun getStudentInfo() {
//            val student = Student("fancycy", 10)
//            student.study()
    }

    /**
     * init方法，替代以前的construct方法
     */
    fun getStudentInfo1() {
        val student = Student("zjm", 20, "1234", 90)
        val user = UserBean("fancy", 20)
    }

    fun getUserInfo() {
        val user = UserBean("fancy", 20)
        println("用户信息：" + user.toString())
    }


    /**
    ======================********四、List*********=======================
     */


    fun buildList() {
//        VERSION = 3;
        val list = ArrayList<Int>()
        list.add(1)
        list.add(2)
        list.add(3)
        list.add(2, 9)
//            for ((index, i) in list.withIndex()) {
//                println(index)
//            }

        val list1 = listOf<Int>(1, 2, 3, 4)
//            for (i in list1) {
//                println(i)
//            }

        val list2 = mutableListOf<Int>(9, 6, 3, 0)
        list2.add(-3)
        for (value in list2) {
            println(value)
        }


    }

    fun buildMap() {
        val map = HashMap<String, String>()
        map.put("1", "this is 1")
        //Kotlin中map支持类似下标的赋值和访问
        map["2"] = "this is 2"
//            println(map["2"])
//            println(map.get("1"))

        //不可变
        val map2 = mapOf<Int, String>(3 to "this is 3", 4 to "this is 4")
        for ((key, value) in map2) {
            println("" + key + "=" + value)
        }

    }

    /**
    ======================********四、Lambda*********=======================
     */
//    companion object {
//        const val VERSION = 1
    fun maxByOrNull() {
        val list = listOf<String>("a", "aba", "aabbee", "a")
//            var maxStr=""
//           for ( str in list){
//              if (str.length>maxStr.length){
//                  maxStr=str
//              }
//
//           }
//            println("" + maxStr + "=" + maxStr)
//

        //maxByOrNull 数组中的最大元素
        val list1 = listOf<Int>(99, 300, 20, 3)
        var lambda = { numner: Int -> numner }
        var maxStr = list1.maxByOrNull(lambda)
        println("maxStr=" + maxStr)


        var maxStr1 = list.maxByOrNull { name: String -> name.length }
        var maxStr2 = list.maxByOrNull({ name: String -> name.length })
        var maxStr3 = list.maxByOrNull() { name: String -> name.length }
        //若Lambda只有一个参数，则可用it替代参数名
        var maxStr4 = list.maxByOrNull() { it.length }
        println("maxStr4=" + maxStr4)


        val newList = list.map { it.uppercase() }.filter { it.length > 2 }
//            println("newList="+ newList.toString())

        //any返回Boolean，集合中是否存在元素满足Lambda的条件，有则返回true，无则false
        val isAny = list.any { it.length > 0 }
        println("isAny=" + isAny)


    }


    fun forEachItem() {
        val str1 = "abcdefg"
        str1.forEach {
            println("字母：$it")
        }

        val str2 = "12345"
        str2.forEach { a ->
            println("数字：$a")
        }
    }
//    }

    /**
    ======================********五、数据转换*********=======================
    Int	    整型
    long	Long	长整型
    short	Short	短整型
    float	Float	单精度浮点型
    double	Double	双精度浮点型
    boolean	Boolean	布尔型
    char	Char	字符型
    byte	Byte	字节型

    1、 常量：  const val  b="bbb" 不适用于局部，只能声明到   companion object伴生函数里面
    （编译时常量只能在函数之外定义，就可以在编译期间初始了）
    只读类型： val a="324324"//只读的变量
    2、

     */


    /**
    1、字符串转化为整型相关的转化尽量用此函数：toIntOrNull()：Parses the string as an Int number and returns the result or null if the string is not a valid
    val  num2 :Int? ="444.44".toIntOrNull()  num2返回为null
    2、num3 ?: "原来是空"
    3、
     */
    fun funParse() {
        val num: Int = "666".toInt()
        val num1: Int = 444.44.toInt()//结果444
//            val num2: Int="444.44".toInt()//结果4 java.lang.NumberFormatException: For input string: "444.44"
        val num2: Int? = "444.44".toIntOrNull()
        println(num2)


        val num3: Int? = "444.44".toIntOrNull()
        println(num3 ?: "原来是空")

        val a = "324324"//只读的变量
        val day = 5;
        var c = when (day) {
            1 -> "1"
            2 -> "2"
            3 -> "3"
            4 -> "4"
            else -> {
                "hahha"
            }

        }
    }

    fun getDay1(day: Int) = when (day) {
        1 -> "1"
        2 -> "2"
        3 -> "3"
        4 -> "4"
        else -> {
            "hahha"
        }
    }


    /**
    1.字符串模版 ${garden}  $time
    2. 写if else 逻辑 "server response result: ${ if (isLogin) "恭喜成功" else "很遗憾失败" }")
     */
    fun stringMoudle() {
        val garden = "花园"
        val time = 6
        println("今天去${garden}了， 玩了$time 小时")

        val isLogin = true
        println("server response result: ${if (isLogin) "恭喜成功" else "很遗憾失败"}")


    }

    fun getUserInfo1(name: String = "", age: Int = 0): String {
        return "姓名${name} ,年龄 $age"
    }

    //unit相当于void
    fun getUserInfo2(name: String = "", age: Int = 0): Unit {
    }

    fun showgrades(number: Int) {
        when (number) {
            -1 -> TODO("没有这种分数")
            in 0..100 -> println("差生")
            in 100..130 -> println("优秀")
            else -> {
                println("分数错误")
            }
        }

        KtBase22.`in`()
    }

    /*
     kotlin中反引号中函数名特点 ``
     1、`in` In在java里面是关键字体 用``能继续用这个方法
     2、 `2024年12月19日的一个测试函数`（“张三”，20）
     3、34683164（“张三”，20）防止反编译，内部人员公司有加密的私有的文档    34683164===此函数的作用xxx
    * */
    fun `34683164`(name: String, age: Int) {
        println("用户名 $name,年龄$age")
    }

    fun `2024年12月19日的一个测试函数`(name: String, age: Int) {
        println("用户名 $name,年龄$age")
    }


    /**
     * 匿名函数
     */
    fun getFun() {
        val name = "happy"
        val count = name.count {
            it == 'p'
        }
        println("happy中有$count 个p字符")
        println(createMethod2(1, 2, 3))
        createMethod2.invoke(1, 2, 3)
    }

    /*声明函数方法二*/
    val createMethod2: (Int, Int, Int) -> String = { num1, num2, num3 ->
        println("结果： ${num1 + num2}")
        (num1 + num3).toString()
    }

    /*it关键字体的讲解*/
    val creatMethod3: (Double) -> String = {
        "$it 元"
    }

    /*匿名函数的类型推断*/
    /*
    方法名后接冒号 createMethod3: 必须指定 参数类型和返回类型
    方法名= 类型推断返回值
    * */
    val method1 = { v1: Double, v2: Float, v3: Int ->
        "$v1 $v2 $v3"
    }

    //当返回值不确定，为any类型，可能是Int,可能是String类型
    val dayMethod = { v1: Int ->
        when (v1) {
            1 -> {
                "星期一"
            }

            2 -> {
                "星期二"
            }

            else -> {
                -1
            }
        }
    }
    val addMethod = { v1: Int, v2: Float ->
        //第一种写法
        loginAPI("fancy", "1234", { msg: String, code: Int ->
            println(msg + code)
        })

        //第二种写法
        loginAPI("fancy", "1234", responseResult = { msg: String, code: Int ->
            println(msg + code)
        })

        //第三种写法
        loginAPI("fancy", "1234") { msg: String, code: Int ->
            println(msg + code)
        }

        //第四种写法
      val obj=  ::methodResponseResult
        loginAPI("fancy", "1234", ::methodResponseResult)
    }

    /*
     函数类型的引用（传递函数类型对象）
     lambda是函数类型的 对象=  responseResult: (String, Int) -> Unit)
   *
   * */
    fun methodResponseResult(msg: String, code: Int) {
        println("最终登录的成果是：msg：$msg, cod:$code")
    }


    //java中的接口回调替换，用方法当参数暴露结果
    /**
     * inline 内联函数：有lambda作为参数，需要申请内联函数，目的能减少性能损耗
     * 如果无此内联关键字，在调用端，会生产多个对象来完成lambda的调用
     */
    inline fun loginAPI(name: String, pwd: String, responseResult: (String, Int) -> Unit) {
        if (name == null || pwd == null) {
            TODO("用户名和密码为null")
        }
        if (name.length > 3 && pwd.length > 3) {
            if (webServiceLoginAPI(name, pwd)) {//登陆成功
                responseResult("success", 200)
            } else {
                responseResult("failed", 400)
            }
        }

    }

    fun webServiceLoginAPI(name: String, pwd: String): Boolean {
        return name == FANCY && pwd == PWD
    }


    /*
  4、 函数作为返回值类型
  * */
    fun show() {
        val showPrint = showMethod("我是函数作为返回值类型")
        println(showPrint(FANCY, "31"))
    }

    fun showMethod(info: String): (name: String, age: String) -> String {
        return { name: String, age: String ->
            "这个方法是$info,我是$name,今年$age 岁了"
        }
    }

    /*
      5、 匿名函数和具名函数
      * */

    fun show5() {
        //匿名函数 最后的一个参数是lambda可以写在括号外面{}
        showPersonInfo(FANCY, "31") {
            println("显示结果：$it")//以为lambda只有一个参数所以可以用it来代替
        }

        showPersonInfo2(FANCY,"31",showResult={ info: String, age:Int->

        });

        showPersonInfo2(FANCY,"31",{ info: String, age:Int->

        });

        showPersonInfo2(FANCY,"31"){ info: String, age:Int->

        };



        //具名函数
        showPersonInfo(FANCY, "31", ::showResultImpl)

    }

    inline fun showPersonInfo(name: String, age: String, showResult: (String) -> Unit) {
        val str = "我是$name,今年$age 岁了"
        showResult(str)
    }

   inline fun showPersonInfo2(name: String, age: String, showResult:(String,Int)->Unit){
       val str = "我是$name,今年$age 岁了"
       showResult(str,2)
   }

    fun showResultImpl(it: String) {
        println("显示结果2：$it")
    }


    /**
    ======================********六、Kotlin安全调用操作符*********=======================
     */
    companion object {
        const val FANCY = "fancy"
        const val PWD = "1234"
        fun main() {
            //1.？的调用
            var name: String? = "fancy"
            name = "fancycy"
            val capitalize = name?.capitalize()//为空就返回null，不继续执行
            println("结果是：$capitalize")
        }

        //2、kotlin中使用内置函数，实现空安全的调用
        fun mainLet() {
            var name: String? = null
            name="Liuyifei"
            val namelet = name?.let {
                if (it.isBlank()) {
                    "default"
                } else {
                    "[$it]"
                }

            }
            println(namelet)
        }
        //3、非空断言操作符  !! 可能空指针崩溃

        //4、if 判断是否为空的补救措施

        //5、空合并操作符号
        fun mainLetNUll() {
           var info:String?="李小龙"
            info=null
            println(info?:"值为空了")
            println(info?.let { "[$it]"}?:"值为空了")
        }
        //6、substring
        fun mainSub(){
            val name="fancy is"
            println(name.substring(0,name.indexOf("i"))+"====")
            println(name.substring(0 until name.indexOf('i'))+"===")

        }

        //6、Split
        fun mainSplit(){
            val str="fancy,cathy,lucy,nancy"
            val list = str.split(',')
            println(list)
           //解构到参数中
            val(v1,v2,v3,v4)=list
            println("v1:$v1,v2:$v2")


        }
    }


}


interface A {
    fun show()

}

class AImpel : A {
    override fun show() {
        TODO("Not yet implemented")//下面这句话不执行会崩溃
    }

}
































